class: center, middle, inverse, title-slide # R + Markdown: automatización desde
un mail a una tesis
### Richard Detomasi y Gabriela Mathieu
###
<style=‘font-size: 80%;’> FCS - Educación Permanente
Taller ggplot
--- # ¿Qué haremos hoy? - Tipos de gráficos <br><br> -- - Introducción al paquete <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >ggplot2</span> <br><br> -- - Gráficos interactivos: <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >plotly</span> con <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >ggplot2</span> <br><br> -- - Extensiones a ggplot2 <br><br> -- - Mapas estáticos con sf y ggplot2 <br><br> -- - Mapas interactivos con leaflet --- # Recursos recomendados (gráficos) - [El libro de ggplot2](https://ggplot2-book.org/) <br><br> - [Listado de funciones](https://ggplot2.tidyverse.org/reference/) <br><br> - [Fundamentals of data visualization](https://clauswilke.com/dataviz/index.html) <br><br> - [Tutorial](http://r-statistics.co/ggplot2-Tutorial-With-R.html) <br><br> - [R charts](https://r-charts.com/) <br><br> - [R graph gallery](https://r-graph-gallery.com/ggplot2-package.html) <br><br> - [Paletas de colores](https://grafify-vignettes.netlify.app/colour_palettes.html) --- # Recursos comendados (mapas) - [R spatial](https://r-spatial.org/) <br><br> - [Spatial Data Science](https://keen-swartz-3146c4.netlify.app/) <br><br> - [Geocomputation with R](https://geocompr.robinlovelace.net/) <br><br> - [StatnMap](https://statnmap.com/) <br><br> - [Paquete sf](https://r-spatial.github.io/sf/index.html) <br><br> - [Paquete viridis](https://cran.r-project.org/web/packages/viridis/vignettes/intro-to-viridis.html) <br><br> - [Paquete ggspatial](https://paleolimbot.github.io/ggspatial/) <br><br> - [Paquete leaflet](https://rstudio.github.io/leaflet/) <br><br> - [Paquete tidygeocoder](https://jessecambon.github.io/tidygeocoder/) <br><br> - [Video](https://www.youtube.com/watch?v=kIID5FDi2JQ) --- # Tipos de gráficos | Gráfico | Descripción | x | y | |---------|-------------|---|---| |**histograma** (histogram)| distribución de una variable cuantitativa | sí | no | |**densidad** (density)| distribución de una variable cuantitativa |sí |no| |**dispersión** (scatter)| correlación entre 2 variables |sí |sí | | **barra** (bar) | frecuencias de una variable categórica | sí| no | | **barra** (grouped bar) | frecuencias de una v. categórica según otra categórica | sí| sí | | **líneas** (lines) | evolución de una variable a través del tiempo | sí| sí | | **caja** (box) | dispersión de los valores de una variable | sí| no| | **circular** (pie) | frecuencias de una variable categórica | sí| no | y muchos más... [ejemplos de gráficos en R](https://www.r-graph-gallery.com/ggplot2-package.html) --- class: inverse, center, middle # ggplot2 --- # Gramática de gráficos - La <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >gramática del lenguaje</span> nos ayuda a construir frases con sentido a partir de las palabras. <br><br> -- - La <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >gramática de los gráficos</span> nos ayuda a construir figuras gráficas a partir de diferentes elementos visuales. <br><br> -- - Se puede pensar cada <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >gráfico</span> como un <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >conjunto de capas de imágenes</span>, donde la apariencia de cada imagen se basa en algún aspecto del conjunto de datos. <br><br> -- - Fue desarrollada originalmente por Leland Wilkinson y luego adaptada por Hadley Wickham para describir los componentes de un gráfico. --- # Gramática de gráficos .left-column[  ] .right-column[ <br> ggplot2 permite hacer los gráficos por <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >capas</span>, es decir, elementos que se van agregando. Hay diferentes capas pero existen <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >3 fundamentales</span> para hacer gráficos, <br><br> - <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >data</span>: el data frame que contiene las variables que vamos a graficar <br><br> - <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >aesthetics mapping</span>: las variables que vamos a graficar y en dónde (x, y) <br><br> - <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >geometry</span>: el tipo de gráfico que haremos (puntos, líneas, barras, etc.) <br><br> - **capas adicionales** para mejorar el gráfico (título, etiqueta, nombres de ejes, tamaño de letras, etc.) ] --- # Capas | Elemento | Descripción | Función | |---------------|:-------------:|:------:| |Data |Set de datos a plotear | ggplot() | |Aesthetics | Variables a mapear | aes() | |Geometry | El tipo de gráfico a realizar| geom_*() | |Facets | Para ploteos múltiples| facet_*() | |Statistics | Transforma las variables (count, density, etc.)| stat_*() | |Scales | Para cambiar las propiedades de todas las dimensiones estéticas asignadas a los datos | scale_*() |Coordinate | Cartesianas, polares, etc. | coord_*() | |Themes | Estilos de gráficos | theme_*()| [Listado de funciones](https://ggplot2.tidyverse.org/reference/) --- # Capas fundamentales  - Las 3 primeras capas deben ser en este orden: `data`, `aesthetics`, `geometry` <br><br> -- - Las capas se van superponiendo con un `+` <br><br> -- - La estructura básica es como esta: <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >ggplot</span>(data = <span style=" font-weight: bold; color: deeppink !important;" ><df></span>) <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >+</span> <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >aes</span>(x = <span style=" font-weight: bold; color: deeppink !important;" ><Variable_1></span>, y = <span style=" font-weight: bold; color: deeppink !important;" ><Variable_2></span>) <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >+</span> <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >geom_*</span>() donde * debe reemplazarse por el tipo de gráfico que corresponda (bar, points, etc.) --- # Geometrías  --- # Aesthetics  --- class: inverse, center, middle # ggplot2::geom_point() --- # Elementos de un gráfico Para crear un <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >gráfico</span> es necesario: - Llamar a la función <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >ggplot()</span> que crea un lienzo en blanco y se especifica el <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >data frame</span> a utilizar. -- - Especificar las <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >variables</span> a mapear (deben ser columnas del data frame) en los ejes x e y con la función <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >aes()</span>. -- - Agregar una tercera capa con los objetos geométricos que se mostrarán en el gráfico. Por ejemplo, con la función <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >geom_point()</span> para representar los datos como <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >puntos</span>. <img src="index_files/figure-html/unnamed-chunk-2-1.png" style="display: block; margin: auto;" /> --- # Ejemplo mínimo: ggplot + aes .pull-left[ ```r # Cargo el paquete ggplot2 y los datos de berlin library(ggplot2) load("data/berlin.Rdata") ggplot(data = berlin) + aes(x = number_of_reviews, y = price) ``` ] .pull-right[ <!-- --> ] --- # Ejemplo mínimo: ggplot + aes + geom .pull-left[ ```r ggplot(data = berlin) + aes(x = number_of_reviews, y = price) + * geom_point() ``` ] .pull-right[ <!-- --> ] --- # Ejemplo mínimo: color y transparencia .pull-left[ ```r ggplot(data = berlin) + aes(x = number_of_reviews, y = price) + * geom_point(color = "purple", * alpha = 0.7) ``` ] .pull-right[ <!-- --> ] --- # Un error común .pull-left[ ```r ggplot(data = berlin) + aes(x = number_of_reviews, y = price, * color = "purple") + geom_point() ``` - En <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >aes()</span> se definen los parámetros estéticos de las variables. <br><br> - Aquellos que son fijos como **color = "red"**, **fill = "blue"**, etc. se escriben afuera de aes(). Salvo que el color dependa de una variable... ] .pull-right[ <!-- --> ] --- # Coloreo puntos según variable - Se pueden colorear los puntos en función de otra variable. .pull-left[ ```r ggplot(data = berlin) + aes(x = number_of_reviews, y = price, * color = room_type) + geom_point() ``` ] .pull-right[ <!-- --> ] --- # Combino dplyr con ggplot2 La media de precios es 67.143668 euros, la mediana 45, el máximo 9000. Outliers!!! Vamos a quitar esos alojamientos carísimos y aquellos que no tienen dato en el puntaje de evaluación. ```r library(dplyr) berlin_nout <- berlin %>% filter(!is.na(number_of_reviews)) %>% filter(price < 2000) ``` ```r berlin_nout %>% ggplot(aes(x = number_of_reviews, y = price)) + geom_point() ``` --- # Múltiples geometrías en un mismo gráfico Lo que lo hace realmente potente es que se pueden añadir múltiples geometrías a un gráfico. Volvemos a un gráfico anterior y agregamos una línea suavizada para mostrar la tendencia aproximada de los puntos. .pull-left[ ```r berlin_nout %>% ggplot() + aes(x = number_of_reviews, y = price) + * geom_point() + * geom_smooth() ``` ] .pull-right[ <!-- --> ] --- # Múltiples geometrías .pull-left[ Especificamos un color para cada geometría ```r berlin_nout %>% ggplot() + aes(x = number_of_reviews, y = price) + * geom_point(color = "blue") + * geom_smooth(color = "red") ``` ] .pull-right[ <!-- --> ] --- # Misma estética para todas las geometrías Si especificamos una estética dentro de ggplot(aes()) se pasará a cada geom que le siga. .pull-left[ ```r berlin_nout %>% ggplot() + aes(x = number_of_reviews, y = price, * color = room_type) + geom_point() + geom_smooth(se = FALSE) ``` ] .pull-right[ <!-- --> ] --- # Una estética para cada geometría Podemos especificar una estética para una geometría en particular incluyendo la función <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >aes() dentro de geom_*():</span> .pull-left[ ```r berlin_nout %>% ggplot() + aes(x = number_of_reviews, y = price) + geom_point(aes(color = room_type)) + geom_smooth(se = FALSE) ``` ] .pull-right[ <!-- --> ] --- class: inverse, center, middle # ggplot2::facet_*() --- # Gráficos múltiples .pull-left[ ```r berlin %>% ggplot() + aes(x = number_of_reviews, y = price) + geom_point() + * facet_wrap(~room_type) ``` ] .pull-right[ <!-- --> ] --- # Ejercicio - Trabajar únicamente con los barrios Mitte, Pankow y Neukölln, realizar un diagrama de dispersión entre el precio y la evaluación. <br><br> - Colorear los puntos según room_type. <br><br> - Realiza este mismo gráfico usando <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >facet_wrap()</span>. --- # Agrega título y nombre a ejes .pull-left[ ```r berlin_nout %>% ggplot() + aes(x = number_of_reviews, y = price, color = room_type) + geom_point() + geom_smooth(se = FALSE) + * labs(x = 'Evaluación', * y = 'Precio mediano', * title = 'Alojamientos en Berlin de Airbnb') ``` ] .pull-right[ <!-- --> ] --- class: inverse, center, middle # ggplot:theme_*() --- # Temas - La función <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >theme_*()</span> controla el estilo del gráfico, permite definir el color de fondo, la apariencia de la leyenda, tamaños de letra, etc. <br><br> - Vienen predefinidos una variedad de temas pero también se puede instalar un paquete con más temas `ggthemes`. <br><br> - Explorar otros [temas](https://ggplot2.tidyverse.org/reference/ggtheme.html). <br><br> - Cambiamos el <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >fondo a color blanco</span> al elegir el tema 'bw' <br><br> - También hay paquetes específicos que traen otros temas: `ggthemr`, `hrbrthemes`, `ggdark`, `tvthemes`. --- # Fondo blanco .pull-left[ ```r berlin %>% filter(!is.na(number_of_reviews)) %>% group_by(number_of_reviews) %>% summarize(price = median(price)) %>% ggplot() + aes(x = number_of_reviews, y = price, color = room_type) + geom_point() + geom_smooth(se = FALSE) + labs(x = 'Evaluación', y = 'Precio mediano', title = 'Alojamientos en Berlin de Airbnb') + * theme_bw() ``` ] .pull-right[ <!-- --> ] --- # Centra título .pull-left[ ```r berlin_nout %>% ggplot() + aes(x = number_of_reviews, y = price, color = room_type) + geom_point() + geom_smooth(se = FALSE) + * labs(x = 'Evaluación', * y = 'Precio mediano', title = 'Alojamientos en Berlin de Airbnb') + theme_bw() + * theme(plot.title = element_text(hjust = 0.5)) ``` ] .pull-right[ <!-- --> ] --- # Cambiar las propiedades de las geometrías Dentro de <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >geom_*()</span> es posible manipular el color, forma y tamaño de los puntos. .pull-left[ ```r berlin_nout %>% ggplot() + aes(x = number_of_reviews, y = price, color = room_type) + * geom_point(color = "purple", * shape = "diamond", size = 2) + labs(x = 'Evaluación', y = 'Precio mediano', title = 'Alojamientos en Berlin de Airbnb') ``` <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >ggplot2</span> acepta que el argumento color se escriba: **color**, **colour** o **col** ] .pull-right[ <!-- --> ] --- # Ejercicio - Grafica el precio y el puntaje de evaluación. <br><br> - Colorea los puntos con un color específico, agrega nombre a los ejes y título. <br><br> - Exporta el gráfico a formato pdf <br><br> - Abre el Rmd que venimos editando y agrega el código del gráfico 2. Nombra el chunk. <br><br> - Agrega el gráfico 2 pero a partir del pdf generado. Nombra el chunk. <br><br> - Define los parámetros de cada chunk de tal forma que no se vea el código y se evalúe. <br><br> - Define el tamaño de las figuras: ancho y alto. <br><br> - Modifica el código del gráfico para que no tenga título. Luego agrega el título en el chunk. --- class: inverse, center, middle # Otras geometrías --- # Otras geometrías - Además de los gráficos de dispersión o de puntos, también existen otras geometrías, como los <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >gráficos de barras</span>, por ejemplo. <br><br> -- - Para trabajar con este tipo de gráfico tendremos que adecuar la base de datos. <br><br> -- - Para hacer un gráfico de barras necesitamos generar un data frame con información resumida para cada categoría que se quiera graficar, es decir, <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >información agregada</span> a nivel de cada categoría. <br><br> -- - Ejemplo: creamos un nuevo objeto llamado `nb` que filtra los casos para 3 barrios y calculamos el precio mediano de los alojamientos. --- # Gráfico de barras Vamos a trabajar con un subconjunto de los datos para tener menos categorías de barrios. Creamos un nuevo objeto nb que contiene la mediana de precios para los barrios: Mitte, Neukölln, y Pankow. .pull-left[ ```r nb <- berlin %>% filter(neighbourhood_group %in% c("Mitte", "Neukölln", "Pankow")) %>% group_by(neighbourhood_group) %>% summarize(med.price = mean(price)) nb %>% ggplot(aes(x = neighbourhood_group, y = med.price)) + geom_bar(stat = 'identity') ``` ] .pull-right[ <!-- --> ] - El argumento <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >stat='identity'</span> de la función <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >geom_bar()</span>, indica que la altura de la barra debe ser igual al valor y. --- # Propiedades del texto del eje x .pull-left[ ```r nb %>% ggplot() + aes(x = neighbourhood_group, y = med.price) + geom_bar(stat = 'identity') + * theme(axis.text.x = element_text(angle = 60, * hjust = 1)) ``` La función <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >element_text()</span> la llamo dentro de <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >theme()</span>, debo especificar a qué elemento de texto quiero modificar: <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >axis.text.x</span>. ] .pull-right[ <!-- --> ] --- # Reordeno las categorías de menor a mayor La función reorder() reordena las categorías de una variable según los valores de una variable numérica. El argumento de geom_bar, stat='identity', indica que la altura de la barra debe ser igual al valor y. .pull-left[ ```r nb %>% ggplot() + * aes(x = reorder(neighbourhood_group, med.price), y = med.price) + geom_bar(fill = 'purple', alpha = .7, stat = 'identity') + theme(axis.text.x = element_text(angle = 60, hjust = 1)) + labs(x = '', y = 'Precio promedio', title = 'Precio promedio según barrio') ``` - La función <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >reorder()</span> reordena las categorías de una variable según los valores de una variable numérica. ] .pull-right[ <!-- --> ] --- class: inverse, center, middle # ggplot::coord_flip() --- # Giro el gráfico .pull-left[ ```r nb %>% ggplot() + aes(x = reorder(neighbourhood_group, med.price), y = med.price) + geom_bar(fill = 'purple', alpha = .7, stat = 'identity') + theme(axis.text.x = element_text(angle = 60, hjust = 1)) + labs(x = '', y = 'Precio promedio', title = 'Precio promedio según barrio') + * coord_flip() ``` - La función <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >coord_flip()</span> intercambia las coordenadas cartesianas para que el eje horizontal (x) se convierta en vertical y el vertical (y) en horizontal. ] .pull-right[ <!-- --> ] --- # Ancho de las barras .pull-left[ ```r nb %>% ggplot() + aes(x = reorder(neighbourhood_group, med.price), y = med.price) + geom_bar(fill = 'purple', alpha = .7, * stat = 'identity', width = 0.3) + labs(x = '', y = 'Precio promedio', title = 'Precio promedio según barrio') ``` - Con el argumento <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >width</span> se especifica el grosor de la barra. - **width = 0.3** grafica las barras con un 30% de grosor. - Si no queremos separación entre las barras se debe especificar **width = 1** - El valor por defecto es **width = 0.9**, es decir 90%. ] .pull-right[ <!-- --> ] --- # Gráfico de barras agrupadas .pull-left[ ```r nb <- berlin %>% filter(neighbourhood_group %in% c("Mitte", "Neukölln", "Pankow")) %>% group_by(neighbourhood_group, room_type) %>% summarize(med.price = mean(price)) nb %>% ggplot() + aes(x = neighbourhood_group, y = med.price, fill = room_type) + * geom_bar(position = "dodge", stat = "identity") ``` - La opción <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >dodge</span> del argumento **position** indica realizar agrupamiento horizontal de las categorías. ] .pull-right[ <!-- --> ] --- # Gráfico de barras apiladas .pull-left[ ```r nb %>% ggplot()+ aes(x = neighbourhood_group, y = med.price, fill = room_type) + geom_bar(position = "stack", stat = "identity") ``` - La opción <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >stack</span> del argumento **position** indica realizar agrupamiento vertical de las categorías, es decir, apilarlas. ] .pull-right[ <!-- --> ] --- # gghighlight .pull-left[ ```r library(gghighlight) ggplot(berlin, aes(neighbourhood_group, number_of_reviews, fill = neighbourhood_group)) + coord_flip() + geom_col(width = 0.5) + gghighlight(neighbourhood_group == 'Neukölln', unhighlighted_colour = "cornflowerblue") + scale_fill_manual(values = c("grey")) + theme_bw() + theme(legend.position = 'none') + labs(x = NULL, y = '# Evaluaciones', title = "Cantidad de evaluaciones por barrio") ``` ] .pull-right[ <!-- --> ] --- # Escalas de colores Se pueden escribir los colores de dos formas: <br><br> - <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >manual</span>: - por [nombre](http://www.stat.columbia.edu/~tzheng/files/Rcolor.pdf), - o por [código hexadecimal](https://htmlcolorcodes.com/) <br><br> - <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >automática</span>: usando paletas de colores internas a ggplot2 o de otros paquetes como viridis. La paleta de colores se indica con una función del tipo `scale_colour_*()` para contorno (puntos, líneas) y `scale_fill_*()` para relleno (áreas). El asterisco debe reemplazarse por manual para indicar manualmente los colores. Cuando se quiere usar una paleta automática el asterisco se reemplaza por un nombre concreto. También se admite escribir color, en vez de colour. --- class: inverse, center, middle # ggplot::ggsave() --- # Exportar un gráfico Es preferible el formato pdf ya que se guarda en formato vectorial y así evitamos que se pixele como puede ocurrir con los formatos png, jpg, etc. ```r # pdf ggsave('grafico_berlin.pdf') # jpg ggsave('grafico_berlin.jpg') # png ggsave('grafico_berlin.png') ``` Podemos definir otros argumentos para variar el tamaño del gráfico, entre otras cosas. Para guardarlo en png cambiamos pdf por png. --- # Otros paquetes gráficos - [ggpubr](https://rpkgs.datanovia.com/ggpubr/): gráficos ggplot2 para publicar - todas las [extensiones](https://exts.ggplot2.tidyverse.org/gallery/) de ggplot2 <br><br> - **plotly**: para realizar gráficos interactivos - **gganimation**: para hacer gráficos de ggplot2 interactivos <br><br> - Paquetes que ofrecen variedades de paletas de colores: - viridis - rcartocolor - LaCroixColoR - [jcolors](https://jaredhuling.org/jcolors/) - RColorBrewer --- class: inverse, center, middle # plotly --- # Gráficos animados .pull-left[ ```r *library(plotly) gg <- ggplot(gapminder) + aes(log10(gdpPercap), lifeExp, color = continent, frame = year) + geom_point(aes(size = pop, ids = country)) + geom_smooth(se = FALSE, method = "lm") *ggplotly(gg) ``` - la función <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >ggplotly()</span> del paquete <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >plotly</span> convierte gráficos estáticos de ggplot en dinámicos. ] .pull-right[
] --- class: inverse, center, middle # Mapas --- # GDS (Geographical Data Science) - <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >R no es un SIG</span>(Sistemas de Información Geográficos). ¿Conocen gvSIG, Qgis, etc.? <br><br> -- - R permite <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >hacer Ciencia de Datos Geográficos</span> (SDG) <br><br> -- <br><br> | Atributos | SIG | SDG | |---------------|:-------------:|:-------------:| |Disciplinas | Geografía | Geografía, Computación, Estadística| | Foco | Interfaz Gráfica | Código | | Reproducibilidad | Mínimo | Máximo | --- # Raster vs Vectorial <p align="center"> <img src="img_plot/raster_vector.png" width="500"> </p> <!--  --> --- # Datos espaciales  --- # Paquetes (vectorial / ráster) .pull-left[ - **Conectar R con SIG**: GRASS GIS (rgrass7), SAGA (RSAGA), QGIS (RQGIS y qgisremote), ArcGIS (arcgisbinding). - <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >sp</span>, [<span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >sf</span>](https://r-spatial.github.io/sf/): manejar **información espacial vectorial** utilizan geometría (puntos, polilíneas, polígonos). Por ejemplo, carreteras, árboles, edificios, etc. <img src="img_plot/real_raster_vector.jpg" width="853" style="display: block; margin: auto;" /> ] .pull-right[ - <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >raster</span>: para **trabajar con imágenes**. Representar información que es continua a través de un área y se pierde mucha información si se trabaja en entidades vectoriales. Los ráster se componen de una matriz de píxeles del mismo tamaño, cada uno con un valor que representa las condiciones de la zona cubierta por dicha celda/pixel. ] <!-- https://geocompr.robinlovelace.net/spatial-class.html --> <!-- https://cengel.github.io/R-spatial/ --> <!-- https://www.jessesadler.com/post/gis-with-r-intro/ --> --- # Paquetes para realizar mapas .pull-left[ - **Mapas estáticos** - <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >ggplot2</span>: también sirve para gráficos - <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >tmap</span>: al igual que ggplot2 se basa en la gramática de gráficos y necesita de un objeto de clase sf. Está diseñado para generar mapas temáticos con menos código que ggplot2. ] .pull-right[ - **Mapas interactivos** - <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >tmap</span> - <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >leaflet</span> - <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >mapview</span> ] Un listado más completo de paquetes para trabajar con información espacial podés ver [acá](https://cran.r-project.org/web/views/Spatial.html). --- # Sistema de coordenadas .pull-left[ - Es un sistema para <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >codificar cada una de las posiciones sobre la superficie de la tierra</span> y asignar a estas las correspondientes coordenadas. <br><br> - La forma de la tierra se aproxima a un elipsoide, por lo que se usan elementos de la geometrı́a esférica para definir el sistema de referencia. <br><br> - <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >Sistema de coordenadas geográficas</span>: es un sistema de coordenadas esféricas mediante el cual un punto se localiza con dos valores angulares, <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >longitud</span> y <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >latitud</span>. Los <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >paralelos</span> permiten medir la <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >latitud</span> / Los <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >meridianos</span> permiten medir la <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >longitud</span> Imagen: [Sistemas de Información Geográfica](https://volaya.github.io/libro-sig/), Victor Olaya. ] .pull-right[ .center.w-10[ <img src="img_plot/lat_lon.png" width="300"/> <!--  --> ] ] --- # Proyecciones cartográficas La geometrı́a plana resulta mucho más intuitiva y práctica que la geometrı́a esférica para realizar ciertos cálculos. El proceso de <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >asignar una coordenada plana a cada punto de la superficie de la Tierra</span> (que no es plana) se conoce como proyección cartográfica. Las proyecciones cartográficas, tratan de situar los elementos de la superficie del elipsoide sobre una superficie plana. Se obtienen coordenadas cartesianas (la posición de un punto se define mediante un par de medidas de distancia x e y). Pero este proceso no es perfecto, se producen <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >distorsiones</span>. Existen diversas proyecciones de mapa que ofrecen distintas propiedades. En algunas se mantiene la forma y, en otras, la distancia. En otras se mantiene el área o la dirección. .center.w-40[ <iframe src="https://giphy.com/embed/S8xBpak0epddCpcI0k" width="480" height="294" frameBorder="0" class="giphy-embed" allowFullScreen></iframe><p><a href="https://giphy.com/gifs/big-bang-olavo-de-carvalho-terraplana-S8xBpak0epddCpcI0k"></a></p> ] --- # Proyecciones cartográficas Mercator vs. Gall-Peters ([Video](https://www.youtube.com/watch?v=kIID5FDi2JQ) ) <img src="img_plot/mercator_gallpeters.png" width="937" style="display: block; margin: auto;" /> --- class: inverse, center, middle # sf --- # sf - Un paquete para trabajar con datos espaciales en R. <br><br> -- - **Simple Features** es un estándar para la representación de objetos espaciales de la vida real a través de geometrías -puntos, lineas, polígonos, etc. - en los sistemas de información geográfica. El paquete sf implementa este estándar en R. <br><br> -- - Combina las funcionalidades de 3 paquetes: **sp**, **rgeos** y **rgdal** <br><br> -- - Ventajas respecto a otros paquetes: <br><br> - Mayor **velocidad** para importar y exportar los datos <br><br> - Más tipos de **geometrías** soportadas <br><br> - **Compatibilidad** con tidyverse. Funciona el pipe! --- # sf - El paquete **sp** es predecesor de sf. <br><br> -- - Muchos paquetes espaciales de R todavía dependen del paquete sp, por lo tanto, es importante saber cómo **convertir**. <br><br> -- - Convertir objetos **sf** a **sp** ```r # Para transformar de SF a SP objeto.sp <- as(<objeto.sf>, "Spatial") ``` -- - Convertir objetos **sp** a **sf** ```r # Para transformar de SP a SF objeto.sf <- st_as_sf(<objeto.sp>) ``` --- # data.frame a espacial - Cuando tenemos un data.frame que tiene por ejemplo coordenadas de puntos, podemos convertirlos a objetos de clases espaciales... ```r library(sp) base_sp <- SpatialPoints(base[,c("x","y")], proj4string = CRS("+init=epsg:32721")) library(sf) base_sf <- st_as_sf(base, coords = c("x","y"), crs = 32721) ``` - Nota: Los dos `crs` más utilizados para Uruguay son según su código EPSG: `32721` y `4326` --- # Objetos de clase sf - Los objetos sf tienen una <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >clase</span> que combina **'data.frame'** y **'sf'** <br><br> -- - Los objetos sf también tienen una columna especial que contiene los datos de <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >geometría</span>, usualmente llamado 'geom' o **'geometry'**. <br><br> -- - Las funciones del paquete <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >dplyr</span> se pueden aplicar. Para saber la totalidad de funciones que son aplicables a un objeto de **clase 'sf'** consultar **methods()**. <br><br> -- - Los archivos con datos espaciales se leen con la función <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >st_read()</span>. <br><br> - Para la unión de objetos espaciales se usa <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >st_join(x, y)</span>. El método de join utilizado es siempre **left_join()**, manteniendo los registros del primer atributo. <br><br> - La visualización de la información espacial se puede realizar con <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >ggplot2</span> usando <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >geom_sf()</span>. --- # Estructura de datos espaciales - El formato más común de archivos que contienen datos espaciales son los <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >shapefiles</span>. <br><br> - Este formato creado por ESRI, la misma empresa que creo ArcGIS, se volvió el **estándar**. <br><br> - Este archivo de extensión **.shp** viene junto a otros con extensión **.dbf** y **.shx**, pero podría venir con otros más. <br><br> - Para usarlos deben mantenerse juntos en la misma carpeta. <br><br> - Otros formatos habituales son: geoJSON, XML, geoPackage, etc. Un listado más completo se puede ver [acá](https://mappinggis.com/2013/11/los-formatos-gis-vectoriales-mas-populares/). --- # Shapefiles - Tipos de datos espaciales: - **Puntos**: una sola ubicación descrita por un punto. - **Líneas**: un segmento compuesto por una serie de puntos conectados entre sí que no forman un objeto cerrado. - **Polígonos**: una superficie plana compuesta por una serie de líneas conectadas entre sí que forman un objeto cerrado. - **Multi-polígonos**: Multi-superficies compuestas de polígonos que no necesariamente se intersectan. <div class="figure"> <img src="img_plot/figure_forms.png" alt="Fuente: https://arcruz0.github.io/libroadp/maps.html" width="765" /> <p class="caption">Fuente: https://arcruz0.github.io/libroadp/maps.html</p> </div> --- # ¿De dónde obtenemos las capas con información geográfica? - Dependiendo del país, será la institución oficial que las provea. <br><br> - En Uruguay una gran cantidad de información encontrarán en la [<span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >IDE</span>](https://www.gub.uy/infraestructura-datos-espaciales/). <br><br> - Un paquete de R para trabajar con datos de Uruguay es [<span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >geouy</span>](https://richdeto.github.io/geouy/) <br><br> - Hay varios paquetes de R que ya traen información geográfica para hacer mapas del mundo o determinados países. <br><br> - En otros casos deberemos <span style=" font-weight: bold; border-radius: 4px; padding-right: 4px; padding-left: 4px; background-color: #b3e2cd !important;" >importar la información geográfica</span> que puede venir en archivos de formato shp, geojson, etc. --- # Capas disponibles en geouy - Instituciones como: - IDE, - INE, - IM, - MVOTMA, entre otros - Tipo de capas: - límites administrativos (deptos, secciones, etc.) - hidrología - caminos (rutas, calles, etc.) - servicios públicos - etc. --- # Importar shapes ```r # cargo paquete library(sf) # importo shapes barrios = st_read("data/berlin_shapefile/GISPORTAL_GISOWNER01_BERLIN_BEZIRKE_BOROUGHS01.shp", stringsAsFactors = FALSE) ``` ``` ## Reading layer `GISPORTAL_GISOWNER01_BERLIN_BEZIRKE_BOROUGHS01' from data source ## `/home/calcita/Escritorio/Proyectos_github/netlify slides/rmd-fcs/rmd-2022-5/data/berlin_shapefile/GISPORTAL_GISOWNER01_BERLIN_BEZIRKE_BOROUGHS01.shp' ## using driver `ESRI Shapefile' ## Simple feature collection with 12 features and 3 fields ## Geometry type: MULTIPOLYGON ## Dimension: XY ## Bounding box: xmin: 13.08835 ymin: 52.33824 xmax: 13.76114 ymax: 52.67551 ## Geodetic CRS: WGS 84 ``` ```r # consulto clase class(barrios) ``` ``` ## [1] "sf" "data.frame" ``` ```r # consulto métodos methods(class = "sf") ``` --- class: inverse, center, middle # Mapas estáticos --- # Mapa de coropletas - Una forma básica de ver la distribución espacial de nuestras variables es con la función `plot()` a nuestro objeto `sf`. <br><br> -- - Es un **mapa temático** en el que las regiones se colorean de un motivo que muestra una **medida estadística**. <br><br> -- - Para hacer una salida gráfica más atractiva usaremos `ggplot2` <br><br> -- - [Buenas prácticas](https://blog.datawrapper.de/choroplethmaps/) --- # Datos Berlin ```r # cargo datos load("data/berlin.Rdata") ``` -- - Hay un problema de encoding? ```r library(stringi) ``` ```r # con qué encoding vienen los datos? stri_enc_mark(barrios$BezName) ``` ```r library(dplyr) # defino que los lea como 'ISO-8859-1' y pase a 'UTF-8' barrios <- barrios %>% mutate(BezName = stri_conv(BezName, from = 'ISO-8859-1', to = 'UTF-8', to_raw = FALSE)) head(barrios$BezName, 12) ``` ``` ## [1] "Mitte" "Friedrichshain-Kreuzberg" ## [3] "Pankow" "Charlottenburg-Wilmersdorf" ## [5] "Spandau" "Steglitz-Zehlendorf" ## [7] "Tempelhof-Schöneberg" "Neukölln" ## [9] "Treptow-Köpenick" "Marzahn-Hellersdorf" ## [11] "Lichtenberg" "Reinickendorf" ``` --- # Expresiones regulares ```r # los barrios están escritos igual? table(unique(berlin$neighbourhood_group) %in% barrios$BezName) ``` ``` ## ## FALSE TRUE ## 5 7 ``` ```r # busco la expresión y reemplazo library(stringr) large <- barrios$BezName small <- berlin$neighbourhood_group berlin <- berlin %>% mutate(neighbourhood_group = stri_replace(str = small,regex = small, replacement = large , mode = "all")) # chequeo table(unique(berlin$neighbourhood_group) %in% barrios$BezName) ``` ``` ## ## TRUE ## 12 ``` --- # ggplot2 ```r # cuento la cantidad de alojamientos por barrios bn <- berlin %>% group_by(neighbourhood_group) %>% summarise(median_price = median(price)) # uno berlin con el objeto espacial barrios bn <- left_join(bn, barrios, by = c("neighbourhood_group" = "BezName")) %>% st_as_sf() # calculo centroides de los polígonos y se los agrego al objeto bn bn <- barrios %>% st_centroid() %>% st_coordinates() %>% as.data.frame() %>% bind_cols(bn, .) library(ggplot2) mapa <- ggplot(bn) + geom_sf(aes(geometry = geometry, fill = median_price)) + geom_text(aes(x = X, y = Y, label = neighbourhood_group), colour = "white", size = 3, hjust = 0.5) + scale_fill_viridis_c("# Alojamientos", option = "D") + ggtitle("Alojamientos Airbnb por barrios de Berlin") ``` --- # ggplot2 <img src="index_files/figure-html/unnamed-chunk-67-1.png" style="display: block; margin: auto;" /> --- # Seteamos el tema Seteamos los parámetros de la función theme() y lo guardamos en el objeto theme_base ```r #redefinimos el theme (marco para los gráficos) theme_base <- theme( axis.line = element_blank(), axis.text.x = element_blank(), axis.text.y = element_blank(), axis.ticks = element_blank(), axis.title.x = element_blank(), axis.title.y = element_blank(), legend.text = element_text(size = 11), legend.title = element_text(size = 12), panel.background = element_blank(), panel.border = element_rect(colour = "gray", fill = NA, size = 0.5), legend.justification = c(1,1), legend.position = c(1,1) ) ``` --- # Modifico tema .pull-left[ ```r mapa + theme_base ``` ] .pull-right[ <!-- --> ] --- # Agrego norte y escala .pull-left[ ```r library(ggspatial) mapa + theme_base + annotation_scale(location = "bl", width_hint = 0.4) + annotation_north_arrow(location = "tl", which_north = "true", height = unit(0.7, "cm"), width = unit(0.7, "cm"), pad_x = unit(0.095, "in"), pad_y = unit(0.025, "in"), style = north_arrow_fancy_orienteering) ``` ] .pull-right[ <!-- --> ] --- class: inverse, center, middle # Mapas interactivos --- # leaflet - Leaflet es una librería de JavaScript para mapas interactivos <br><br> - El paquete leaflet de R es la adaptación para usarla fácilmente en R <br><br> - Para hacer una búsqueda en internet sobre alguna función de leaflet en R es recomendable escribir "leaflet r" y lo que se busca. De no escribir "r" probablemente las referencias sean en código js. <br><br>  <br><br> - [Tutorial](https://rstudio.github.io/leaflet/) para comenzar. --- # leaflet() Un mapa leaflet también podemos pensarlo como una serie de capas que se llaman con ciertas funciones. | Función | Descripción | |---------------|:-------------:| | leaflet() |crea el objeto leaflet | | addTiles() | define el mapa de base, un mosaico| | setView() | define donde estará centrado y el zoom | | addMarkers() | marcadores a partir de una capa espacial o de pares de coordenadas.| El orden de los comandos es importante. --- # Ejemplo mínimo Por defecto, el mapa de base es un mosaico de OpenStreetMap que aparece al usar la función addTiles(). [Otras opciones](http://leaflet-extras.github.io/leaflet-providers/preview/) .pull-left[ ```r library(leaflet) leaflet() %>% addTiles() ``` ] .pull-right[
] --- # Agrego marcadores - En la función addMarkers defino las coordenadas del o los puntos a mapear: donde *lng* es la longuitud y *lat* la latitud. <br><br> - El paquete leaflet espera que todos los datos de puntos, líneas y formas se especifiquen en latitud y longitud utilizando WGS 84 (EPSG:4326). Si tomamos coordenadas de google maps u open street maps estarán en esta proyección. .pull-left[ ```r library(leaflet) mapa <- leaflet() %>% addTiles() %>% addMarkers(lng = -56.18307, lat = -34.90604, popup = "FCS") mapa ``` ] .pull-right[
] --- # Agrego un ícono - Puedo usar un ícono específico para mostrar los puntos. - Creo el ícono con la función makeIcon() y lo defino dentro de addMarkers con el argumento icon. .pull-left[ ```r url_logo <- "https://cienciassociales.edu.uy/wp-content/uploads/2020/02/Logotipo-institucional-FCS_N2_RGB_PNG-transparente.png" logo_fcs <- makeIcon(url_logo, url_logo, 56, 24) leaflet() %>% addTiles() %>% addMarkers(lng = -56.18307, lat = -34.90604, popup = "FCS", icon = logo_fcs) ``` ] .pull-right[
] --- # Alojamientos Berlin Ahora vamos a mapear varios puntos a partir de un data frame que contiene un subconjunto de los alojamientos de Berlin. .pull-left[ ```r # Alojamientos caros de Airbnb en Berlin top <- filter(berlin, price > 500 & !is.na(number_of_reviews)) # agrego info de barrio barrios_top <- left_join(barrios, top, by = c("BezName" = "neighbourhood_group")) %>% st_as_sf() # mapeo polígonos de barrio, colorea por cantidad de alojamientos mapa <- leaflet(data = barrios_top) %>% addTiles() %>% addPolygons(weight = 1, color = "green", fillColor = "yellow", popup = ~BezName) mapa ``` ] .pull-right[
] --- # Ejercicio - Agregar los puntos de los 74 alojamientos más caros de Berlin, donde el ícono del marcador sea un ícono de Airbnb. <br><br> - Agregar un popup que indice nombre del alojamiento, precio y puntaje de evaluación. <br><br> - Agregar un control de capas que permita apagar la capa de polígonos y/o la de puntos. --- # Exportar los gráficos - Los gráficos que generemos en el Rmd se verán en el documento final pero no se guardaran como archivos aparte. <br><br> - Para guardar los gráficos en archivos individuales, escribimos en el YAML: <br><br> keep_md: true <br><br> - Esto crea algunas carpetas llamadas "FILENAME_files" - puedes controlar el nombre específico de la carpeta estableciendo fig.path así <br><br> knitr::opts_chunk$set(fig.path = "figs")